iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0
Python

利用Python完成自動化測試專案系列 第 10

D10 實作發文自動化(3) 完成

  • 分享至 

  • xImage
  •  

今天要把發文自動化完成,首先要先講到如何用 json 存取檔案。

json

json 是把資料呈現成JavaScript的標準格式,它的架構是由大括號組合而成。以下用存放網站的帳號密碼做舉例:

{
    "webA": {
        "id": 123
        "password": 456
    },
    "webB": {
        "id": 789
        "password": 012
    }
}

像這樣透過一個又一個的大括號包裝起來,而我們的結構如下:

{
    "subject": "(文章標題)",
    "article": "(文章內容)"

}

在 python 使用 json

首先要先 import json,這個部分在昨天和前天載入環境變數的時候已經有使用過了

import json

再來要讀取 json 檔案,我們打開 json 檔案並讀取它:

with open('irondata.json', 'r', encoding='utf-8') as file:
    irondata = json.load(file)
    day10_subject = irondata["subjevt"]
    day10_article = irondata["article"]

這樣就完成讀取了,再來我們繼續往下實作,首先我們先把元素定位出來:

# 輸入文章主旨
subject = browser.find_element(By.XPATH, "//input[@class='form-control post-header__title']")
# 輸入文章內容
article = browser.find_element(By.CSS_SELECTOR, ".CodeMirror")
# 點擊倒三角 icon
more_icon = browser.find_element(By.XPATH, "//button[contains(@class, 'btn')]/span[@class='caret']")
# 點擊發表文章
send_article = browser.find_element(By.XPATH, "//button[text()='發表文章']")

這邊可以發現 more_icon 的 XPATH 寫法不太一樣,原因是我們原本要定位的 span 會有重複的元素,所以我們從上面一個節點開始往下找 span 即可定位到我們要的元素。

再來是輸入文章與發表

# 輸入文章標題和內容
subject.send_keys(day10_subject)

actions.click(article).perform()
actions.send_keys(day10_article).perform()

browser.execute_script("arguments[0].scrollIntoView();", more_icon)
more_icon.click()
send_article.click()

可以看到這邊輸入文章多了一點步驟,而這就要提到 CodeMirror 這個東西。

CodeMirror

這是一個 JS 的套件,可以在網頁端編輯 code,而 iT 邦幫忙在文章內文就有使用這個套件,而它無法用一般 text 或是 textfield 的方式去輸入,這個時候只能靠 Action Chains

Action Chains

它負責鼠標的所有操作,基本上我們能做到的他都能夠實現,它強大的部分是可以把鼠標的功能像鎖鏈一樣連起來,以實現各種複雜的操作(例如拖拉物件等等)。

而我們在 Action Chains 操作的點擊與輸入,與 selenium 相較之下模擬的更加逼真,所以我們的操作才能被 CodeMirror 捕捉到。

把這些搞定後,自動化發文終於到一段落。

資料來源&完整程式碼

CodeMirror的操作: How do I edit CodeMirror with Selenium in Python?

import json
import os
import time

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

from dotenv import load_dotenv


# 設定 ChromeDriver 的路徑

browesr_path = "c:\Program Files\chromedriver-win64\chromedriver-win64\chromedriver.exe"

service = Service(browesr_path)

# 設定 Chrome 的啟動參數
options = Options()

# 設定瀏覽器語言為中文
options.add_argument("--lang=zh-TW")

# 全螢幕模式
options.add_argument("--kiosk")

browser = webdriver.Chrome(service=service, options=options)

browser.get("https://ithelp.ithome.com.tw/")

# 設定 action chain
actions = ActionChains(browser)

# 前往登入頁面
login_page_button = browser.find_element(By.XPATH, "//a[@class='menu__item-link']")

login_page_button.click()

# 登入帳號密碼
account = browser.find_element(By.ID, "account")
password = browser.find_element(By.ID, "password")
login_button = browser.find_element(By.ID, "loginBtn")

load_dotenv()
ITHOMELOGIN = json.loads(os.getenv("ITHOMELOGIN"))

account.send_keys(ITHOMELOGIN["account"])
password.send_keys(ITHOMELOGIN["password"])
login_button.click()

# 進到鐵人發文頁面

iron_button = browser.find_element(By.XPATH, "//button[@class='menu__ironman-btn']")
select_topic_button = browser.find_element(By.XPATH, "//a[@class='ir-modal__list-link']")

iron_button.click()
time.sleep(1)
select_topic_button.click()

# 貼上文章並發文

with open('irondata.json', 'r', encoding='utf-8') as file:
    irondata = json.load(file)

day10_subject = irondata["subject"]
day10_article = irondata["article"]

# 等待網頁載入
time.sleep(1)

subject = browser.find_element(By.XPATH, "//input[@class='form-control post-header__title']")
article = browser.find_element(By.CSS_SELECTOR, ".CodeMirror")
more_icon = browser.find_element(By.XPATH, "//button[contains(@class, 'btn')]/span[@class='caret']")
send_article = browser.find_element(By.XPATH, "//button[text()='發表文章']")

# 輸入文章標題和內容
subject.send_keys(day10_subject)

actions.click(article).perform()
actions.send_keys(day10_article).perform()


browser.execute_script("arguments[0].scrollIntoView();", more_icon)
more_icon.click()
send_article.click()

time.sleep(5)

以上是整個自動化發文的 code ,可以發現隨著專案的擴大,看 code 會越來越辛苦,因此明天預計會介紹 POM(Page Object Model)的形式,讓 code 不會擠成一團難以閱讀與維護外,也能夠讓專案符合物件導向的精神。


上一篇
D9 實作發文自動化(2)
下一篇
D11 Page Object Model
系列文
利用Python完成自動化測試專案12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言